#pragma once

#include "NetworkConnection.h"
#include "NetworkPackets.h"
#include "../engine/Singleton.h"

#include <vector>
#include <queue>
#include <list>

namespace Putin{

class RtsConnection;


/*!
 * \brief
 * Client side network communication
 * 
 * The class is responsible for wrapping the network connection 
 * as well as correctly handling packets.
 * 
 * \remarks
 * Write remarks for NetworkClient here.
 * 
 * \see
 * Separate items with the '|' character.
 */
class NetworkClient : public Singleton<NetworkClient>
{
public:

	enum State
	{
		DISCONNECTED	= 0,
		WAITING_GO		= 1,
		RUNNING			= 2
	};

	typedef std::vector<NetworkCommand> CommandVector;
	typedef std::vector<NetworkText>	TextVector;
	typedef std::queue<NetworkCommand>	CommandQueue;
	typedef std::queue<NetworkText>		TextQueue;

	typedef std::list<NetworkText>		TextList;

	NetworkClient(void);
	virtual ~NetworkClient(void);

	/*!
	 * \brief Start the client and connect to an IP
	 */
	bool connect( std::string ip );

	void disconnect();

	/*!
	 * \brief get the state of client
	 *
	 * \returns the state
	 */
	State getState(){return mState;}
	bool  getStart(){return mStart;}
	void  setNotStart(){mStart = false;}

	// TODO: Add lobby stuff

	void updateKeyFrame(int frameCount);

	void send(NetworkPacket* pack);

	/*!
	 * \brief Updates and checks for messages
	 */
	void update(); 

	CommandQueue& getCommands();
	TextList& getTexts();
	

	// -- Packet handlers that are executed as callbacks --

	/*! 
	 * \brief Handle an incomming packet
	 */
	void handlePacket(NetworkConnection* net,NetworkPacket* np);
	
	/*! 
	 * \brief Handle a newly established connection
	 */
	void handleConnect(NetworkConnection* net, NetworkPacket* np);

	/*!
	 * \brief Handle a disconnect
	 */
	void handleDisconnect(NetworkConnection* net, NetworkPacket* np);


	/*! 
	 *  To be overridden by a class defined by the game implementor 
	 *  to specify the behaviour more detailed.
	 */
	virtual void handleCommand(NetworkConnection* net, NetworkCommand* nc);

	/*! 
	 *  To be overridden by a class defined by the game implementor 
	 *  to specify the behaviour more detailed.
	 */
	virtual void handleText(NetworkConnection* net, NetworkText* nc);


protected:

	RtsConnection*	mConnection;
	State			mState;

	CommandQueue	mCommands;
	TextList		mTexts;

	bool			mStart;
};


} // end namespace Putin